/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.caelum.interceptor;

import br.com.caelum.controller.CarrinhoController;
import br.com.caelum.controller.ProdutoController;
import br.com.caelum.controller.UsuarioController;
import br.com.caelum.dao.EntidadeDao;
import br.com.caelum.dao.PermissaoDao;
import br.com.caelum.dao.RecursoDao;
import br.com.caelum.interceptor.AutenticacaoInterceptor.Restrito;
import br.com.caelum.model.Entidade;
import br.com.caelum.model.Permissao;
import br.com.caelum.model.Recurso;
import br.com.caelum.model.Usuario;
import br.com.caelum.model.UsuarioWeb;
import br.com.caelum.vraptor.InterceptionException;
import br.com.caelum.vraptor.Intercepts;
import br.com.caelum.vraptor.Result;
import br.com.caelum.vraptor.core.InterceptorStack;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.ioc.SessionScoped;
import br.com.caelum.vraptor.resource.ResourceMethod;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.List;

/**
 *
 * @author estagiario
 */
@Intercepts(after = AutenticacaoInterceptor.class)
@SessionScoped
public class UsuarioInterceptor implements Interceptor {

    private UsuarioWeb usuarioWeb;
    private Result result;

    public UsuarioInterceptor(UsuarioWeb usuarioWeb, Result result) {
        this.usuarioWeb = usuarioWeb;
        this.result = result;
    }

    public void intercept(InterceptorStack is, ResourceMethod rm, Object o) throws InterceptionException {
        result.redirectTo(UsuarioController.class).inicio();
    }

    public boolean accepts(ResourceMethod rm) {
        Permissao permissao = new Permissao();

        Entidade entidade = buscaClasse(rm);

        permissao = (verificaPermissao(entidade, permissao, rm.getMethod().getName()));

        return (this.usuarioWeb.isLogado() && !permissao.getPermissao());
    }

    @Retention(RetentionPolicy.RUNTIME) //a anotação vai ficar disponível em tempo de execucao
    @Target(ElementType.METHOD) // anotação para métodos
    public @interface Res {
    }

    private Entidade buscaClasse(ResourceMethod rm) {
        String nomeClasse = rm.getResource().toString();

        nomeClasse = nomeClasse.replace(".", ";");
        nomeClasse = nomeClasse.replace("}", "");

        String[] nClasse = nomeClasse.split(";");

        for (String x : nClasse) {
            nomeClasse = x;
        }

        return new EntidadeDao().buscarNome(nomeClasse);
    }

    private Permissao verificaPermissao(Entidade entidade, Permissao permissao, String nomeMetodo) {
        Usuario usuario = usuarioWeb.getLogado();

        RecursoDao daoRecurso = new RecursoDao();

        PermissaoDao daoPermissao = new PermissaoDao();

        List<Recurso> recurso = daoRecurso.buscarRecurso(nomeMetodo, entidade.getId());

        if (usuario != null) {
            List<Permissao> p = (List<Permissao>) daoPermissao.buscarPorIdGrupo(usuario.getGrupo().getId(), recurso.get(0).getId());
            
            if (p != null) {
                permissao.setPermissao(p.get(0).getPermissao());
                return permissao;
            }else{
                permissao.setPermissao(false);
            }
            
        }else{
            permissao.setPermissao(false);
        }        
        return permissao;
    }
}